package com.ifonly.interceptor;

import java.util.ArrayList;
import java.util.List;

/**
 * @author <a href="mailto:ifonlymaster@163.com">ifonly</a>
 * @version 1.0 2015-12-10 16:06
 * @since JDK 1.6
 */
public class InterceptorBuilder {

    public static Interceptor[] build(Interceptor[] globalInterceptors,
                                      Interceptor[] classInterceptors,
                                      Interceptor[] methodInterceptors,
                                      Class<? extends Interceptor>[] ignores) {

        List<Class<? extends Interceptor>> includes = new ArrayList<Class<? extends Interceptor>>();
        List<Interceptor> results = new ArrayList<Interceptor>();

        addToList(globalInterceptors, ignores, includes, results);
        addToList(classInterceptors, ignores, includes, results);

        //Method上面的拦截器不会忽略,即使是进行了 ignore 配置
        if (methodInterceptors != null && methodInterceptors.length > 0) {
            for (Interceptor i : methodInterceptors) {
                Class<? extends Interceptor> target = i.getClass();
                if (!includes.contains(target)) {
                    results.add(i);
                }
            }
        }

        return results.toArray(new Interceptor[results.size()]);
    }

    private static void addToList(Interceptor[] interceptors,
                                  Class<? extends Interceptor>[] ignores,
                                  List<Class<? extends Interceptor>> includes,
                                  List<Interceptor> results) {

        if (interceptors != null && interceptors.length > 0) {
            for (Interceptor i : interceptors) {
                Class<? extends Interceptor> target = i.getClass();

                if (!includes.contains(target) && !exclude(ignores, target)) {
                    results.add(i);
                }
            }
        }

    }

    private static boolean exclude(Class<? extends Interceptor>[] ignores, Class<? extends Interceptor> target) {
        if (ignores == null) {
            return false;
        }
        if (ignores.length == 0) {
            return true;
        }

        for (Class<? extends Interceptor> clazz : ignores) {
            if (clazz == target) {
                return true;
            }
            if (clazz.equals(target)) {
                return true;
            }
            if (clazz.getName().equals(target.getName())) {
                return true;
            }
        }

        return false;
    }

}
